Skip to content

Conversation

@mifu67
Copy link
Contributor

@mifu67 mifu67 commented Oct 22, 2025

Actions use new -> old model serializers even if the workflow engine objects were single written, and thus we were failing to serialize and failing to send actions if the lookup table objects do not exist.

To fix this, if we cannot find a lookup table equivalent for a workflow engine object, set a fake ID for it equal to (workflow engine object ID + ONE BILLION). This is safe because the serialized legacy IDs are not used for action firing, with the exception of charts.

The charts will not show incident demarcation lines until we switch to using the open period serializer instead of the incidents serializer; however, because the actions currently fail to send at all, I feel that this is acceptable until the chart change lands.

@mifu67 mifu67 requested a review from a team as a code owner October 22, 2025 22:47
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Oct 22, 2025
@mifu67 mifu67 requested a review from a team October 22, 2025 22:48
cursor[bot]

This comment was marked as outdated.

alert_rule_id=alert_rule_id
)
except AlertRuleDetector.DoesNotExist:
detector_id = int(alert_rule_id) - OFFSET
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This operation is a bijection so fetching the detector ID works out nicely :)

Comment on lines +335 to +337
alert_rule_id = AlertRuleDetector.objects.values_list(
"alert_rule_id", flat=True
).get(detector=obj)
Copy link

@semgrep-code-getsentry semgrep-code-getsentry bot Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Risk: Affected versions of Django are vulnerable to Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). SQL injection in Django's ORM column aliases: when using QuerySet.annotate(), QuerySet.alias(), QuerySet.aggregate(), or QuerySet.extra() with dictionary expansion (**kwargs), the dictionary keys are used unescaped as SQL column aliases. On MySQL and MariaDB backends, an attacker who can influence those keys (for example, by passing a crafted dict of annotations) can inject arbitrary SQL into the generated query.

Manual Review Advice: A vulnerability from this advisory is reachable if you are using Django with MySQL or MariaDB

Fix: Upgrade this library to at least version 5.2.7 at sentry/uv.lock:305.

Reference(s): GHSA-hpr9-3m2g-3j9p, CVE-2025-59681

🎉 Fixed in commit 8c89442 🎉

Comment on lines +59 to +61
alert_rule_trigger_id = DataConditionAlertRuleTrigger.objects.values_list(
"alert_rule_trigger_id", flat=True
).get(data_condition=detector_trigger)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High severity vulnerability may affect your project—review required:
Line 59 lists a dependency (django) with a known High severity vulnerability.

ℹ️ Why this matters

Affected versions of Django are vulnerable to Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). SQL injection in Django's ORM column aliases: when using QuerySet.annotate(), QuerySet.alias(), QuerySet.aggregate(), or QuerySet.extra() with dictionary expansion (**kwargs), the dictionary keys are used unescaped as SQL column aliases. On MySQL and MariaDB backends, an attacker who can influence those keys (for example, by passing a crafted dict of annotations) can inject arbitrary SQL into the generated query.

References: GHSA, CVE

To resolve this comment:
Check if you are using Django with MySQL or MariaDB.

  • If you're affected, upgrade this dependency to at least version 5.2.7 at uv.lock.
  • If you're not affected, comment /fp we don't use this [condition]
💬 Ignore this finding

To ignore this, reply with:

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

You can view more details on this finding in the Semgrep AppSec Platform here.

@codecov
Copy link

codecov bot commented Oct 22, 2025

Codecov Report

❌ Patch coverage is 94.44444% with 2 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
.../endpoints/serializers/workflow_engine_detector.py 81.81% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           master   #101974      +/-   ##
===========================================
+ Coverage   80.97%    80.98%   +0.01%     
===========================================
  Files        8729      8740      +11     
  Lines      388412    388830     +418     
  Branches    24628     24628              
===========================================
+ Hits       314502    314907     +405     
- Misses      73550     73563      +13     
  Partials      360       360              

Copy link
Member

@kcons kcons left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable to me, but I think the value of OFFSET should be set once and documented, and potentially abstracted via some trivial helper functions.
Bonus points if we use them to improve type safety (we don't really have well-typed ID types, so probably not).

cursor[bot]

This comment was marked as outdated.

Comment on lines +337 to +339
alert_rule_id = AlertRuleDetector.objects.values_list(
"alert_rule_id", flat=True
).get(detector=obj)
Copy link

@semgrep-code-getsentry semgrep-code-getsentry bot Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Risk: Affected versions of Django are vulnerable to Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'). SQL injection in Django's ORM column aliases: when using QuerySet.annotate(), QuerySet.alias(), QuerySet.aggregate(), or QuerySet.extra() with dictionary expansion (**kwargs), the dictionary keys are used unescaped as SQL column aliases. On MySQL and MariaDB backends, an attacker who can influence those keys (for example, by passing a crafted dict of annotations) can inject arbitrary SQL into the generated query.

Manual Review Advice: A vulnerability from this advisory is reachable if you are using Django with MySQL or MariaDB

Fix: Upgrade this library to at least version 5.2.7 at sentry/uv.lock:305.

Reference(s): GHSA-hpr9-3m2g-3j9p, CVE-2025-59681

🍰 Fixed in commit e878183 🍰

@mifu67 mifu67 merged commit 3f56d58 into master Oct 27, 2025
69 checks passed
@mifu67 mifu67 deleted the mifu67/aci/old-new-serializer-id-patch branch October 27, 2025 23:18
priscilawebdev pushed a commit that referenced this pull request Oct 28, 2025
… old model equivalents (#101974)

Actions use new -> old model serializers even if the workflow engine
objects were single written, and thus we were failing to serialize and
failing to send actions if the lookup table objects do not exist.

To fix this, if we cannot find a lookup table equivalent for a workflow
engine object, set a fake ID for it equal to (workflow engine object ID
+ ONE BILLION). This is safe because the serialized legacy IDs are not
used for action firing, with the exception of charts.

The charts will not show incident demarcation lines until we switch to
using the open period serializer instead of the incidents serializer;
however, because the actions currently fail to send at all, I feel that
this is acceptable until the chart change lands.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants